<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>河南地图</title>
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<link type="text/css" rel="stylesheet" href="./css/base.css">
        <script src="./js/TweenMax.min.js"></script>
        <style>
            .canvas-list{
                display:none;
            }
        </style>
    </head>
    <body>
        <div class="canvas-list" id="name_list"></div>
        
        <div id="container"></div>
        <script type="module">
            import * as THREE from '../build/three.module.js';
            // import { OrbitControls } from '../examples/jsm/controls/OrbitControls.js';
            import Stats from '../examples/jsm/libs/stats.module.js';
			import { TTFLoader } from '../examples/jsm/loaders/TTFLoader.js';

            THREE.Cache.enabled = true;
            var container, stats,renderer,scene,camera,henanShape,raycaster;
            var canvasBox = document.querySelector("#name_list");
            stats = new Stats();
            document.body.appendChild(stats.dom);
            var ttfLoader = new TTFLoader();
            var mouse = new THREE.Vector2(), INTERSECTED;
            mouse.x = 2;
            mouse.y = 2;

            var senceChanged = true;

            //构建字体
            var font_height = 1,
                font_size = 5,
                font_hover = 10,
                font_curveSegments = 1,
                font_bevelThickness = 1,
                font_bevelSize = 0.1,
                font_three = null,
                font_material = new THREE.MeshBasicMaterial({color:0xefefef,flatShading:true});

            container = document.getElementById( 'container' );
            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
            camera.position.set( 0, 150, 500 );
            scene = new THREE.Scene();
            scene.background = new THREE.Color( 0x050505 );
            scene.add( camera );

            var light = new THREE.PointLight( 0xffffff, 0.3 );
            camera.add( light );

            // var directionalLight = new THREE.DirectionalLight( 0xffffff, .3 );
            // directionalLight.position.set( 0.5, 0, .5).normalize();
            // scene.add( directionalLight );

            var groupOld = null;
            var boundLoader = new THREE.FileLoader();

            raycaster = new THREE.Raycaster();
            //自定义属性
            // lineMesh.userData.originalScale = 11;
            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.outputEncoding = THREE.sRGBEncoding;
            // maxTimes = mapMesh.geometry.vertices.length;
            // console.log(maxTimes);
            container.appendChild( renderer.domElement );
            // var controls = new OrbitControls( camera, renderer.domElement );

            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            document.addEventListener( 'click', chooseCity, false );

            ttfLoader.load( './css/font-dome/webfont.ttf', function ( json ) {
                font_three = new THREE.Font( json );
                init(getCodeByName());
            } );

            
			// animate();
            function init(code){
                console.log('run init');
                let group = new THREE.Group();
                if(groupOld != null){
                    //这里是关键只要把这些对象dispose掉，就不会增加内存。
                    groupOld.traverse(function(obj) {
                        if (obj.type === 'Mesh' || obj.type === 'Line') {
                            if(obj.geometry.dispose) obj.geometry.dispose();
                            if(obj.material[0]){
                                obj.material[0].dispose();
                                obj.material[1].dispose();
                            }
                            if(obj.material.dispose) obj.material.dispose();
                            if(obj.material.texture && obj.material.texture.dispose) obj.material.texture.dispose();
                        }
                    });
                    scene.remove(groupOld);
                }
                groupOld = group;

                boundLoader.load('./map/henanBound/'+code+'.text',function(bound){
                    let boundMessage = JSON.parse(bound);

                    for(let k=0;k<boundMessage.length;k++){
                        let vector2Points = [];
                        let boundPoints = boundMessage[k].bounder;
                        for(let i=0;i<boundPoints.length;i+=3){
                            vector2Points.push(new THREE.Vector2(boundPoints[i],boundPoints[i+1]))
                        }
                        
                        for ( let i = 0; i < vector2Points.length; i ++ ){
                            if(code == "4100"){
                                vector2Points[ i ].multiplyScalar( 0.5 );
                            }else{
                                vector2Points[ i ].multiplyScalar( 2 );
                            }
                        } 
                        
                        henanShape = new THREE.Shape(vector2Points);
                        let extrudeSettings = { depth: 20, bevelEnabled: true, bevelSegments: 8, steps: 5, bevelSize: 1, bevelThickness: 10 };

                        let heNangeometry = new THREE.ExtrudeBufferGeometry( henanShape, extrudeSettings );
                        // let planeMater = createCanvasMater(boundMessage[k].cityName);
                        let mapMesh = new THREE.Mesh( heNangeometry, [new THREE.MeshPhongMaterial( { color: 0xffff00 } ),new THREE.MeshPhongMaterial( { color: 0xffffff } )] );
                        mapMesh.userData.name = boundMessage[k].cityName;
                        group.add(mapMesh);

                        //添加区域边界线
                        let LineGeometry = new THREE.BufferGeometry();
                        LineGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( boundPoints, 3 ) );
                        let lineMaterial = new THREE.LineBasicMaterial( { color: 0xff9900 } );
                        let lineMesh = new THREE.Line( LineGeometry, lineMaterial );
                        if(code =="4100"){
                            lineMesh.scale.set( 0.5,0.5,0.5 );
                        }else{
                            lineMesh.scale.set( 2,2,2 );
                        }
                        lineMesh.position.z = 31;
                        group.add( lineMesh );

                        // /////////添加文字平面,这是基于canvas添加的字体库。
                        // let planGeometry = new THREE.PlaneGeometry( 45, 20 );
                        // let planMaterial = createCanvasMater(boundMessage[k].cityName);
                        // let planeName = new THREE.Mesh( planGeometry, planMaterial );
                        // if(code =="4100"){
                        //     planeName.position.x = boundMessage[k].cityCenter.x/2;
                        //     planeName.position.y = boundMessage[k].cityCenter.y/2;
                        // }else{
                        //     planeName.position.x = boundMessage[k].cityCenter.x*2;
                        //     planeName.position.y = boundMessage[k].cityCenter.y*2;
                        // }
                        // planeName.position.z = 31;
                        // planeName.scale.set( 0.5,0.5,0.5 );
                        // group.add( planeName );


                        //添加文字平面,这是基于ttf字体库添加的文字。
                        let textMesh = createCityName(boundMessage[k].cityName);
                         if(code =="4100"){
                            textMesh.position.x = boundMessage[k].cityCenter.x/2;
                            textMesh.position.y = boundMessage[k].cityCenter.y/2;
                        }else{
                            textMesh.position.x = boundMessage[k].cityCenter.x*2;
                            textMesh.position.y = boundMessage[k].cityCenter.y*2;
                        }
                        group.add( textMesh );
                       
                    }

                    group.rotation.x = -Math.PI/3;
                    group.scale.set(0.2,0.2,0.2);
                    group.position.y = 50;

                    scene.add( group );
                    camera.lookAt( scene.position );
                    senceChanged = false;
                    animate();
                })
            }
            function createCityName(name){
                let textGeo = new THREE.TextBufferGeometry( name, {
                    font: font_three,
                    size: font_size,
                    height: font_height,
                    curveSegments: font_curveSegments,
                    bevelThickness: font_bevelThickness,
                    bevelSize: font_bevelSize,
                    bevelEnabled: true
                } );
                textGeo.computeBoundingBox();
				textGeo.computeVertexNormals();
				let centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
				let textMesh = new THREE.Mesh( textGeo, font_material );
                // textMesh.translateX(centerOffset);
                textMesh.position.z = 30;
                return textMesh;
            }
            //实时证明他们会使用同一个canvas渲染。
            function createCanvasMater(name){
                let dmcanvas = document.createElement("canvas");
                dmcanvas.width = "45";
                dmcanvas.height = "20";
                canvasBox.appendChild(dmcanvas);

                let drawingContext = dmcanvas.getContext( '2d' );
                drawingContext.fillStyle = '#818118';
                drawingContext.fillRect(0, 0, 45, 20);

                drawingContext.fillStyle = 'rgb(255, 255, 255)';
                drawingContext.font = "16px serif";
                drawingContext.fillText(name, 0, 16);
                
                let material = new THREE.MeshBasicMaterial();
                material.map = new THREE.CanvasTexture( dmcanvas );
                return material;
            }
            function onDocumentMouseMove( event ) {
                event.preventDefault();
                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
            }
            function chooseCity(event){
                event.preventDefault();
                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
                raycaster.setFromCamera( mouse, camera );
                let intersects = raycaster.intersectObjects( scene.children[1].children );
                if ( intersects.length > 0 ) {
                    if ( intersects[ 0 ].object.geometry.type == "ExtrudeBufferGeometry") {
                        let name = intersects[ 0 ].object.userData.name;
                        senceChanged = true;
                        init(getCodeByName(name));
                    }
                }else{
                    senceChanged = true;
                    init(getCodeByName());
                }
            }
            function getCodeByName(name){
                switch (name) {
                    case "郑州市":
                        return "4101";
                    case "开封市":
                        return "4102";
                    case "洛阳市":
                        return "4103";
                    case "平顶山市":
                        return "4104";
                    case "安阳市":
                        return "4105";
                    case "鹤壁市":
                        return "4106";
                    case "新乡市":
                        return "4107";
                    case "焦作市":
                        return "4108";
                    case "濮阳市":
                        return "4109";
                    case "许昌市":
                        return "4110";
                    case "漯河市":
                        return "4111";
                    case "三门峡市":
                        return "4112";
                    case "南阳市":
                        return "4113";
                    case "商丘市":
                        return "4114";
                    case "信阳市":
                        return "4115";
                    case "周口市":
                        return "4116";
                    case "驻马店市":
                        return "4117";
                    case "济源市":
                        return "419001";
                    default:
                        return "4100"
                }
            }
            function animate(){
                render();
                stats.update();
                TweenMax.to(groupOld.rotation, 2, {x:-Math.PI/8});
                TweenMax.to(groupOld.scale, 2, {x:1.2,y:1.2,z:1.2});
                if(!senceChanged){
                    requestAnimationFrame( animate );
                }
            }
            function render() {
                raycaster.setFromCamera( mouse, camera );
                let intersects = raycaster.intersectObjects( scene.children[1].children );
                if ( intersects.length > 0 ) {
                    if ( INTERSECTED != intersects[ 0 ].object && intersects[ 0 ].object.geometry.type == "ExtrudeBufferGeometry") {
                        if ( INTERSECTED ) INTERSECTED.material[0].emissive.setHex( INTERSECTED.currentHex );
                        INTERSECTED = intersects[ 0 ].object;
                        INTERSECTED.currentHex = INTERSECTED.material[0].emissive.getHex();
                        INTERSECTED.material[0].emissive.setHex( 0xff0000 );
                    }
                } else {
                    if ( INTERSECTED ) INTERSECTED.material[0].emissive.setHex( INTERSECTED.currentHex );
                    INTERSECTED = null;
                }
                scene.overrideMaterial = null;
                renderer.clear();
                renderer.render( scene, camera );
            }
        </script>
    </body>
</html>